﻿using System;
using System.Data.Entity;
using System.Diagnostics.CodeAnalysis;
using System.Linq;

namespace NQueries
{
    /// <summary>
    /// Abstract interace for the data context.
    /// </summary>
    public interface IDataContext : IDisposable
    {
        /// <summary>
        /// Gets or sets the Timeout value, in seconds, for all data context operations.
        /// A null value indicates that the default value of the underlaying provider will be used.
        /// </summary>
        int? CommandTimeout { get; set; }

        /// <summary>
        /// Gets the query for the given entity type.
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <returns></returns>
        [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Set", Justification = "Overrides property by this name given by Microsoft. They should use their own validation rules I assume.")]
        IDbSet<TEntity> Set<TEntity>() where TEntity : class;

        /// <summary>
        /// Gets the query for the given entity type.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Set", Justification = "Overrides property by this name given by Microsoft. They should use their own validation rules I assume.")]
        IQueryable Set(Type type);

        /// <summary>
        /// Finds the entity with the given type and primary key values.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        object Find(Type type, params object[] keyValues);

        /// <summary>
        /// Sends pending changes to the database.
        /// </summary>
        /// <returns>The number of objects that have its state changed.</returns>
        int SaveChanges();

        /// <summary>
        /// Attaches an entity and markes it as modified.
        /// </summary>
        /// <param name="entity"></param>
        /// <typeparam name="TEntity"></typeparam>
        void Update<TEntity>(TEntity entity) where TEntity : class;
    }
}